//package com.allwees.data.analysis.stat.service.impl;
//
//import com.allwees.bs.core.model.stat.EStatType;
//import com.allwees.bs.core.modelbase.constant.EPlatform;
//import com.allwees.bs.core.modelbase.vo.R;
//import com.allwees.core.common.util.reflect.ReflectionUtils;
//import com.allwees.core.elasticsearch.query.QueryParams;
//import com.allwees.core.elasticsearch.query.sql.EsSqlQuery;
//import com.allwees.data.analysis.stat.EStatMode;
//import com.allwees.data.analysis.stat.dao.StatDao;
//import com.allwees.data.analysis.stat.entity.BaseStatEntity;
//import com.allwees.data.analysis.stat.req.QueryStatReq;
//import com.allwees.data.analysis.stat.service.StatService;
//import com.allwees.data.analysis.stat.vo.StatDetailVo;
//import com.allwees.data.analysis.stat.vo.StatVo;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//
//import java.util.ArrayList;
//import java.util.Date;
//import java.util.List;
//
//@Slf4j
//public abstract class BaseStatServiceImpl<
//		E extends BaseStatEntity,
//		SD extends StatDetailVo,
//		S extends StatVo<SD>,
//		M extends StatDao<E, SD, S>,
//		Q extends QueryStatReq> implements StatService<Q> {
//    private Class<E> boClass;
//
//	public BaseStatServiceImpl() {
//		boClass = ReflectionUtils.getGenricParameterType(this.getClass(), BaseStatServiceImpl.class, 0);
//	}
//
//    @Autowired
//    protected EsSqlQuery esSqlQuery;
//
//    @Autowired
//    protected M statDao;
//
//    protected void stat(EStatType statType, Date dateFrom, Date dateTo) {
//        List<E> stats = new ArrayList<>();
//
//        QueryParams params = QueryParams.of();
//        String type = statType.getTypes();
//        if (!StringUtils.isEmpty(type)) {
//            params.put("type", type);
//        }
//        params.put("dateFrom", dateFrom)
//                .put("dateTo", dateTo);
//
//        try {
//            stats = esSqlQuery.query(boClass, getSqlQueryDir() + "/" + statType.name() + ".txt", params);
//        }  catch (NullPointerException ex) {
//            log.warn(" statType:{} msg:{}", statType, ex.getMessage());
//            try {
//                stats = esSqlQuery.query(boClass, "stat_common/" + statType.name() + ".txt", params);
//            }  catch (NullPointerException ex1) {
//                log.warn(" statType:{} msg:{}", statType, ex1.getMessage());
//            }
//        }
//
//        if (CollectionUtils.isEmpty(stats)) {
//            E stat = defaultEntity(statType, dateFrom);
//            stats.add(stat);
//        } else {
//            stats.forEach(stat -> {
//                stat.setDate(dateFrom)
//                    .setStatType(statType)
//                    .setPlatform(stat.getPlatform() != null ? stat.getPlatform() : EPlatform.H5);
//            });
//        }
//        saveStatToDb(stats);
//    }
//
//    private void saveStatToDb(List<E> stats) {
//        for(E stat : stats) {
//            saveStatToDb(stat);
//        }
//    }
//
//    protected abstract E defaultEntity(EStatType statType, Date dateFrom);
//
//    protected abstract void saveStatToDb(E list);
//
//    protected abstract String getSqlQueryDir();
//
//    /*===========================BEGIN OF STAT QUERY========================*/
//
//    protected abstract EStatMode statMode();
//
//	@Override
//	public R singleStat(Q req) {
//        return R.ok(_statByType(req));
//	}
//
//    @Override
//    public R baseStat(Q req) {
//        List<S> datas = new ArrayList<S>() {{
//            addAll(_statByType(req.setStatType(EStatType.SITE_PV)));
//            addAll(_statByType(req.setStatType(EStatType.SITE_UV)));
//            addAll(_statByType(req.setStatType(EStatType.SITE_IPV)));
//            add(_statRateByType(req.setStatType(EStatType.SITE_USER_AVG_COUNT)
//            		.setValueStatType(EStatType.SITE_PV)
//            		.setBaseStatType(EStatType.SITE_UV)));
//            add(_statRateByType(req.setStatType(EStatType.SITE_BOUNCE_RATE)
//            		.setValueStatType(EStatType.SITE_1UV)
//            		.setBaseStatType(EStatType.SITE_UV)));
//            addAll(_statByType(req.setStatType(EStatType.USER_REG)));
//            addAll(_statByType(req.setStatType(EStatType.USER_LOGIN)));
//            addAll(_statByType(req.setStatType(EStatType.USER_LIVENESS)));
//        }};
//        return R.ok(datas);
//	}
//
//    @Override
//    public R bsStat(Q req) {
//        List<S> datas = new ArrayList<S>() {{
//            addAll(_statByType(req.setStatType(EStatType.GMV)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_PAY_COUNT)));
//            add(_statRateByType(req.setStatType(EStatType.ATV)
//            		.setValueStatType(EStatType.GMV)
//            		.setBaseStatType(EStatType.ORDER_PAY_COUNT)));
//            add(_statRateByType(req.setStatType(EStatType.GMV_PER_USER)
//            		.setValueStatType(EStatType.GMV)
//            		.setBaseStatType(EStatType.ORDER_PAY_USER_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_NEW_USER_COUNT)));
//            add(_statRateByType(req.setStatType(EStatType.REGULAR_USER_BUY_RATE)
//            		.setValueStatType(EStatType.ORDER_REGULAR_USER_COUNT)
//            		.setBaseStatType(EStatType.ORDER_USER_COUNT)));
//            add(_statRateByType(req.setStatType(EStatType.LIVENESS_REGULAR_USER)
//            		.setValueStatType(EStatType.ORDER_REGULAR_USER_COUNT)
//            		.setBaseStatType(EStatType.USER_REGULAR)));
//        }};
//        return R.ok(datas);
//    }
//
//	@Override
//	public R orderStat(Q req) {
//        List<S> datas = new ArrayList<S>() {{
//            addAll(_statByType(req.setStatType(EStatType.ORDER_CREATE_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_SKU_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_AMT)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_PAY_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_PAY_SKU_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.GMV)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_REFUND_COUNT)));
//            add(_statRateByType(req.setStatType(EStatType.ORDER_PAY_CONVERSION_RATE)
//            		.setValueStatType(EStatType.ORDER_PAY_USER_COUNT)
//            		.setBaseStatType(EStatType.ORDER_USER_COUNT)));
//            add(_statRateByType(req.setStatType(EStatType.REFUND_RATE)
//            		.setValueStatType(EStatType.SKU_REFUND_COUNT)
//            		.setBaseStatType(EStatType.ORDER_SKU_COUNT)));
//        }};
//        return R.ok(datas);
//	}
//
//	@Override
//	public R userStat(Q req) {
//        List<S> datas = new ArrayList<S>() {{
//            addAll(_statByType(req.setStatType(EStatType.SITE_UV)));
//            addAll(_statByType(req.setStatType(EStatType.USER_LIVENESS)));
//            addAll(_statByType(req.setStatType(EStatType.USER_REG)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_USER_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_PAY_USER_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_REFUND_USER_COUNT)));
//            add(_statRateByType(req.setStatType(EStatType.CLIENT_ORDER_CONVERSION_RATE)
//            		.setValueStatType(EStatType.ORDER_USER_COUNT)
//            		.setBaseStatType(EStatType.P_VIEW_UV)));
//            add(_statRateByType(req.setStatType(EStatType.CLIENT_PAY_CONVERSION_RATE)
//            		.setValueStatType(EStatType.ORDER_PAY_USER_COUNT)
//            		.setBaseStatType(EStatType.P_VIEW_UV)));
//            add(_statRateByType(req.setStatType(EStatType.ORDER_PAY_CONVERSION_RATE)
//            		.setValueStatType(EStatType.ORDER_PAY_USER_COUNT)
//            		.setBaseStatType(EStatType.ORDER_USER_COUNT)));
//        }};
//        return R.ok(datas);
//	}
//
//	@Override
//	public R productStat(Q req) {
//		List<S> datas = new ArrayList<S>() {{
//			addAll(_statByType(req.setStatType(EStatType.P_VIEW_PV)));
//			addAll(_statByType(req.setStatType(EStatType.P_VIEW_UV)));
//			addAll(_statByType(req.setStatType(EStatType.P_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.P_VIEW_COUNT)));
//            add(_statRateByType(req.setStatType(EStatType.P_VIEW_PV_COUNT_RATE)
//            		.setValueStatType(EStatType.P_VIEW_COUNT)
//            		.setBaseStatType(EStatType.P_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.CART_ADD_SKU_COUNT)));
//		}};
//		return R.ok(datas);
//	}
//
//	@Override
//	public R flowStat(Q req) {
//        List<S> datas = new ArrayList<S>() {{
//            addAll(_statByType(req, "HOME_" + req.getLevel()));
//            addAll(_statByTypeAndBsKey(req, "P_LIST_HOT_SELL_TAG_" + req.getLevel()));
//            addAll(_statByTypeAndBsKey(req, "P_LIST_CATEGORY_" + req.getLevel()));
//            addAll(_statByTypeAndBsKey(req, "BANNER_" + req.getLevel()));
//            addAll(_statByTypeAndBsKey(req, "P_LIST_PROMOTION_TAG_" + req.getLevel()));
//        }};
//        return R.ok(datas);
//	}
//
//	@Override
//	public R userConversionFunnel(Q req) {
//        List<S> datas = new ArrayList<S>() {{
//            addAll(_statByType(req.setStatType(EStatType.SITE_UV)));
//            addAll(_statByType(req.setStatType(EStatType.USER_REG)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_USER_COUNT)));
//            addAll(_statByType(req.setStatType(EStatType.ORDER_PAY_USER_COUNT)));
//        }};
//        return R.ok(datas);
//	}
//
//    private List<S> _statByType(Q req, String name) {
//    	req.setStatType(EStatType.valueOf(name));
//    	return _statByType(req);
//    }
//
//    protected List<S> _statByType(Q req) {
//        List<S> stats = statDao.statByType(req);
//        if(CollectionUtils.isEmpty(stats)) {
//        	stats.add(StatVo.newEmptyStat(req));
//        } else {
//			stats.forEach(stat -> stat.complement(req));
//            if(req.isQueryDetail()) {
//                List<SD> details = statDao.statDetailByType(req._clone().setQueryPrev(false));
//                stats.forEach(stat -> {
//					for(SD detail : details) {
//						if(stat.getStatType() == detail.getStatType()) {
//							stat.setDetails(details).complementDetails(req);
//							break;
//						}
//					}
//                });
//            }
//			stats.forEach(stat -> stat.fixValue());
//        }
//        return stats;
//    }
//
//	private S _statRateByType(Q req) {
//		S stat = statDao.statRateByType(req);
//		if(stat == null) {
//			stat = StatVo.newEmptyStat(req);
//		} else {
//			stat.complement(req);
//			if(req.isQueryDetail()) {
//				List<SD> details = statDao.statRateDetailByType(req._clone().setQueryPrev(false));
//				stat.setDetails(details).complementDetails(req);
//			}
//		}
//		return stat;
//	}
//
//    private List<S> _statByTypeAndBsKey(Q req, String name) {
//    	req.setStatType(EStatType.valueOf(name));
//    	return _statByTypeAndBsKey(req);
//    }
//
//	private List<S> _statByTypeAndBsKey(Q req) {
//		List<S> stats = statDao.statByTypeAndBsKey(req);
//		if(CollectionUtils.isEmpty(stats)) {
//			stats.add(StatVo.newEmptyStat(req));
//		} else {
//			stats.forEach(stat -> stat.complement(req));
//			if(req.isQueryDetail()) {
//				stats.forEach(stat -> {
//					List<SD> details = statDao.statDetailByTypeAndBsKey(req._clone().setQueryPrev(false).setBsKey(stat.getBsKey()));
//					stat.setDetails(details).complementDetails(req);
//				});
//			}
//			stats.forEach(stat -> stat.fixValue());
//		}
//		return stats;
//	}
//}
